﻿using System;
using System.ComponentModel.Composition;
using System.Diagnostics;
using System.IO;
using System.Threading.Tasks;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using Microsoft.WebMatrix.Extensibility;
using Microsoft.WebMatrix.Extensibility.Editor;

namespace BuildnDeploy {
    /// <summary>
    /// A sample WebMatrix extension.
    /// </summary>
    [Export(typeof(Extension))]
    public class BuildnDeploy : Extension {

        private Guid _outputTaskTabId = new Guid("67E0F087-D2EB-421C-A96A-3818D491B3AF");

        private IWebMatrixHost _webMatrixHost;

        [Import(typeof(IEditorTaskPanelService))]
        private IEditorTaskPanelService EditorTaskPanelService { get; set; }

        private OutputTab _outputTab;
        private RibbonGroup _ribbonGroup;

        /// <summary>
        /// Initializes a new instance of the BuildnDeploy class.
        /// </summary>
        public BuildnDeploy()
            : base("BuildnDeploy") {
                _buildCommand = new DelegateCommand(BuildWebsite);
                _deployCommand = new DelegateCommand(DeployWebsite);
                _showConfigurationCommand = new DelegateCommand(ShowConfiguration);
        }

        /// <summary>
        /// Perform one time setup operations for this extn
        /// </summary>
        public override void OnInstall() {
            base.OnInstall();
            string settingsFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "BnDCache");
            if (!Directory.Exists(settingsFolder)) {
                Directory.CreateDirectory(settingsFolder);
            }
        }

        /// <summary>
        /// Called to initialize the extension.
        /// </summary>
        /// <param name="host">WebMatrix host interface.</param>
        /// <param name="initData">Extension initialization data.</param>
        protected override void Initialize(IWebMatrixHost host, ExtensionInitData initData) {
            _webMatrixHost = host;

            RibbonButton[] items = new RibbonButton[] {
                            new RibbonButton("Deploy", _deployCommand, null, ImageLibrary.DeployImageSmall, default(BitmapImage)),
                            new RibbonButton("Configure...", _showConfigurationCommand, null, ImageLibrary.ConfigureImageSmall, default(BitmapImage))
                        };

            _ribbonGroup = new RibbonGroup("Build", new RibbonItem[] { new RibbonSplitButton("Build", _buildCommand, null, items, ImageLibrary.BuildImageSmall, ImageLibrary.BuildImageLarge) });

            initData.RibbonItems.Add(_ribbonGroup);
            _webMatrixHost.WebSiteChanged += OnWebSiteChanged;
            EditorTaskPanelService.PageChanged += SetupNewTab;
            SetupNewTab(this, EventArgs.Empty);
        }

        private void OnWebSiteChanged(object sender, EventArgs e) {
            _settings = null;
        }

        private void SetupNewTab(object source, EventArgs e) {
            if (!EditorTaskPanelService.TaskTabExists(_outputTaskTabId)) {
                _outputTab = new OutputTab();
                EditorTaskPanelService.AddTaskTab(_outputTaskTabId, new TaskTabItemDescriptor(null, "Build Output", _outputTab, Brushes.Goldenrod));
                //_outputTab.WriteLine("Tab initialized");
            }
        }

        private ICommand _buildCommand = null;
        private ICommand _deployCommand = null;
        private ICommand _showConfigurationCommand = null;

        private void BuildWebsite(object parameter) {
            ActionWebsite(Settings.BuildCommand);
        }

        private void DeployWebsite(object parameter) {
            ActionWebsite(Settings.DeployCommand);
        }
        
        private void ActionWebsite(string filePath) {
            Process p = null;
            try {
                if (!File.Exists(filePath)) {
                    _outputTab.WriteLine("{0} not found", filePath);
                    return;
                }
                ProcessStartInfo pInfo = new ProcessStartInfo("\"" + filePath + "\"") {
                    UseShellExecute = false,
                    RedirectStandardOutput = true,
                    WindowStyle = ProcessWindowStyle.Hidden
                };
                
                p = Process.Start(pInfo);
                _outputTab.WriteLine(p.StandardOutput.ReadToEnd());
                p.WaitForExit();
                if (p.ExitCode != 0) _outputTab.WriteLine("Process ended with exit code {0}", p.ExitCode);
            }
            catch (Exception ex) {
                _outputTab.WriteLine("The process has an unknown exception:");
                _outputTab.WriteLine(ex.Message);
            }
            finally {
                if (p != null) p.Close();
            }
        }

        Settings _settings;
        Settings Settings {
            get {
                if (_settings == null) {
                    _settings = Settings.LoadForWebsite(_webMatrixHost.WebSite);
                }
                return _settings;
            }
        }

        private void ShowConfiguration(object parameter) {
            SettingsControl sc = new SettingsControl();
            Settings origSettings = new Settings() { BuildCommand = Settings.BuildCommand, DeployCommand = Settings.DeployCommand };
            SettingsViewModel vm = new SettingsViewModel(Settings);
            sc.DataContext = vm;
            bool? result = _webMatrixHost.ShowDialog("Configuration", sc);

            if (result == true) {
                _settings.Save();
            }
            else {
                //revert settings to original here
                Settings.BuildCommand = origSettings.BuildCommand;
                Settings.DeployCommand = origSettings.DeployCommand;
            }
        }
    }
}
